package com.eian.boot.crypto.config;

import com.eian.boot.crypto.core.CryptoService;
import com.eian.boot.crypto.impl.asymmetric.RSADecryptStrategy;
import com.eian.boot.crypto.impl.asymmetric.RSAEncryptStrategy;
import com.eian.boot.crypto.impl.asymmetric.SM2DecryptStrategy;
import com.eian.boot.crypto.impl.asymmetric.SM2EncryptStrategy;
import com.eian.boot.crypto.impl.symmetric.*;
import com.eian.boot.crypto.service.DefaultCryptoService;
import com.eian.boot.crypto.store.InMemoryKeyStore;
import com.eian.boot.crypto.store.KeyStore;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 加密组件自动配置
 *
 * @author eian
 */
@Slf4j
@Configuration
@EnableConfigurationProperties(CryptoProperties.class)
@ConditionalOnProperty(prefix = "eian.crypto", name = "enabled", havingValue = "true", matchIfMissing = true)
public class CryptoAutoConfiguration {

    /**
     * 注册默认密钥存储实现（内存存储）
     * <p>
     * 默认配置：最大1000个密钥，1小时过期
     * <p>
     * 如需自定义实现，可通过 @Primary 注解覆盖此bean
     */
    @Bean
    @ConditionalOnMissingBean
    public KeyStore keyStore() {
        log.info("初始化密钥存储（内存存储）");
        return new InMemoryKeyStore();
    }

    @Bean
    @ConditionalOnMissingBean
    public CryptoService cryptoService(KeyStore keyStore) {
        log.info("初始化加密服务");
        DefaultCryptoService cryptoService = new DefaultCryptoService();

        // 注册对称加密策略
        cryptoService.registerEncryptStrategy(new AESCBCEncryptStrategy());
        cryptoService.registerDecryptStrategy(new AESCBCDecryptStrategy());

        cryptoService.registerEncryptStrategy(new AESGCMEncryptStrategy());
        cryptoService.registerDecryptStrategy(new AESGCMDecryptStrategy());

        cryptoService.registerEncryptStrategy(new SM4CBCEncryptStrategy());
        cryptoService.registerDecryptStrategy(new SM4CBCDecryptStrategy());

        // 注册非对称加密策略
        cryptoService.registerEncryptStrategy(new RSAEncryptStrategy());
        cryptoService.registerDecryptStrategy(new RSADecryptStrategy());

        cryptoService.registerEncryptStrategy(new SM2EncryptStrategy());
        cryptoService.registerDecryptStrategy(new SM2DecryptStrategy());

        // 设置密钥存储
        cryptoService.setKeyStore(keyStore);

        log.info("加密服务初始化完成");
        return cryptoService;
    }

    @Bean
    @ConditionalOnProperty(prefix = "eian.crypto", name = "auto-generate-config", havingValue = "true", matchIfMissing = true)
    public CryptoConfigInitializer cryptoConfigInitializer(CryptoProperties cryptoProperties) {
        return new CryptoConfigInitializer(cryptoProperties);
    }
}

